Amazon EC2 Container Service (ECS)を試してみた
2104/12/20更新 : Dockerの動作に一部不具合があり、ECS-Optimized Amazon LinuxのAMIが更新されました。「3. ECS-Optimized Amazon Linuxの起動」のAMI IDを変更しました。
ども、大瀧です。
AWSのイベント、re:Invent 2014で発表されたDockerコンテナを扱うサービスEC2 Container Service(ECS)のプレビュー申請が通ったので、ドキュメントのチュートリアルを試した様子をレポートします。
1. IAMロールの作成
まずは、Dockerコンテナを実行するEC2インスタンス(ECSインスタンス)からECS APIにアクセスするためのIAMロールを作成します。IAMの管理画面から[Roles] - [Create New Role]で作成ウィザードを表示し、ロール名に「ecs-ec2-role」と入力、[Next Step]をクリックします。
[Select Role Type]画面では、「Amazon EC2」にある[Select]ボタンをクリックします。
[Set Permissions]画面では画面をスクロールし、[Custom Policy]を選択し[Select]ボタンをクリックします。
[Policy Name]には適当なロール名(例: ecs-ec2-role)を入力、[Policy Document]に以下を貼り付けます。
{ "Version": "2012-10-17", "Statement": [ { "Action": "ecs:*", "Effect": "Allow", "Resource": "*" } ] }
[Next Step]をクリックして確認画面に進み、[Create Role]をクリックしてロールが作成されます。
2. ECSクラスタの作成
続いてECSインスタンスをグループとしてまとめるECSクラスタを作成します。ECSクラスタ作成はここからダウンロードできるプレビュー版AWS CLIで行います。プレビュー版AWS CLIでは、aws ecsコマンドでECSを構成、管理することができます。ECSクラスタの作成は、aws ecs create-clusterコマンドを実行します。
$ aws ecs create-cluster --region us-east-1 --cluster-name MyCluster CLUSTER arn:aws:ecs:us-east-1:XXXXXXXXXXXX:cluster/MyCluster MyCluster ACTIVE $ aws ecs list-clusters --region us-east-1 --output json { "clusterArns": [ "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:cluster/MyCluster" ] }
ECSクラスタが作成できました!
3. ECS-Optimized Amazon Linuxの起動
ECSクラスタには、ECSエージェントを実行するEC2インスタンスが参加できます。ECSエージェントは現在、ECS-Optimized Amazon LinuxというDockerインストール済みのAMIを利用するほかに、Docker向けLinuxディストリビューションのCoreOSのAMIが利用できるようです。今回は簡単に試すことができるECS-Optimized Amazon Linuxを利用します。
ECSのプレビューは、現在バージニアリージョン(us-east-1)のみで利用できるため、EC2の管理画面からバージニアリージョンを選択します。
EC2インスタンスの起動ウィザードを表示し[Community AMIs]をメニューから選択、ami-34ddbe5cで検索し表示されるAMIを選択します。
インスタンスタイプの制限は特にないため、t2.microのまま[Next: Configure Instance Details]をクリックします。
詳細設定画面では[IAM Role]を、先ほど作成したIAMロール「ecs-ec2-role」に変更します。
画面をスクロールし、[Advanced Details]を開いて以下のユーザーデータを入力します。
#!/bin/bash echo ECS_CLUSTER=MyCluster >> /etc/ecs/ecs.config
ECSの設定ファイルで、ECSクラスタ名をここで指定するようです。
[Next: Add Storage]をクリックして、ウィザードを進めます。残りの項目は、SSHでログインできるようセキュリティグループを設定すればOKです。適当な設定でウィザードを完了し、インスタンスを起動します。
起動後、しばらく待ってからaws ecs list-container-instancesを実行すると、ECSクラスタのインスタンス一覧に、起動したインスタンスがリストされます。
$ aws ecs list-container-instances --cluster MyCluster --output json --region us-east-1 { "containerInstanceArns": [ "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container-instance/3e7d23ad-a477-4fb3-9a5c-09f8ce7ba76d" ] } $
また、ECSインスタンスにSSHで接続してみます。motdの内容もアレンジされていますw
$ ssh ec2-user@54.85.XX.XX Last login: Thu Dec 18 07:50:32 2014 from XX __| __| __| _| ( \__ \ Amazon ECS-Optimized Amazon Linux AMI ____|\___|____/ Image created: Wed Dec 17 00:19:14 UTC 2014 PREVIEW AMI [ec2-user@ip-172-31-28-157 ~]$
ECSインスタンスでは、ECSエージェントもDockerコンテナとして実行されます。
[ec2-user@ip-172-31-28-157 ~]$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 41172dbd2c52 amazon/amazon-ecs-agent:latest "/agent" 5 minutes ago Up 5 minutes 127.0.0.1:51678->51678/tcp ecs-agent [ec2-user@ip-172-31-28-157 ~]$
エージェントもコンテナで提供される形態は珍しいのではないでしょうか。これでインスタンスの準備はOKです。
4. タスクの登録と実行
ECSでは、実行するDockerコンテナをタスクというグループ単位で管理します *1。タスクは、GKE(Google Container Engine)と同様にテキストデータ(JSON形式)であらかじめ定義し、aws ecs register-task-definition で登録します。タスクの定義ファイルの書式はドキュメントで確認できます。今回はシンプルに、Dockerオフィシャルのbusyboxイメージでsleep 360を実行するコンテナを定義しています。
[ { "environment": [], "name": "sleep", "image": "busybox", "cpu": 10, "portMappings": [], "entryPoint": [ "/bin/sh" ], "memory": 10, "command": [ "sleep", "360" ], "essential": true } ]
$ aws ecs register-task-definition --family sleep360 --container-definitions file://sleep360.json --region us-east-1 --output json { "taskDefinition": { "taskDefinitionArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1", "containerDefinitions": [ { "environment": [], "name": "sleep", "image": "busybox", "cpu": 10, "portMappings": [], "entryPoint": [ "/bin/sh" ], "memory": 10, "command": [ "sleep", "360" ], "essential": true } ], "family": "sleep360", "revision": 1 } } $ aws ecs list-task-definitions --region us-east-1 TASKDEFINITIONARNS arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1 $
タスクが登録されました!続いてタスクを実行するaws ecs run-taskコマンドを実行します。
$ aws ecs run-task --cluster MyCluster --task-definition sleep360:1 --count 1 --region us-east-1 --output json { "tasks": [ { "taskArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task/69e6299c-b85b-43ad-a2d9-0e84944b162a", "overrides": { "containerOverrides": [ { "name": "sleep" } ] }, "lastStatus": "PENDING", "containerInstanceArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container-instance/3e7d23ad-a477-4fb3-9a5c-09f8ce7ba76d", "desiredStatus": "RUNNING", "taskDefinitionArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task-definition/sleep360:1", "containers": [ { "containerArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container/2bcbefb1-d1ca-4d00-a092-f236ad443a8f", "taskArn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:task/69e6299c-b85b-43ad-a2d9-0e84944b162a", "lastStatus": "PENDING", "name": "sleep" } ] } ] } $
タスクが実行されました!コマンドのオプションではECSクラスタを指定しているので、複数のECSインスタンスがある場合は、タスクが自動配置されると考えられます。そのあたりのルール設定などは今後深掘りしていきたいですね。
ECSインスタンスでdocker psを実行すると、確かにタスクに対応するDockerコンテナが実行されていることがわかります。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bf4c172f3416 busybox:latest "sleep 360" 39 seconds ago Up 38 seconds ecs-sleep360-1-sleep-ae8fcfb28383cc9a2700 41172dbd2c52 amazon/amazon-ecs-agent:latest "/agent" 21 minutes ago Up 21 minutes 127.0.0.1:51678->51678/tcp ecs-agent $
まとめ
チュートリアルの範囲でしたが、ECSの構築とDockerコンテナ実行までの簡単な流れは見ていただけたと思います。
Kubernetesとはまた異なる実装のようですので、他のコンテナ管理サービスにあるような可用性やスケジュールに関する機能がECSでどうなっているのか、気になるところですね。引き続きECSをウォッチしていきたいと思います。
脚注
- KubernetesのPodsとReplication Controllerを合わせたような概念のようです ↩